import { marked } from "marked";
import FlowchartJS from "flowchart.js";
import { markedHighlight } from "marked-highlight";
import hljs from "highlight.js";
import markedKatex from "marked-katex-extension";
/**
 * svg 转 img 处理react渲染svg bug
 * @param {string} svgstr
 * @returns {string} svg or img htmlstr
 */

function svgToImg(svgstr) {
  if (unescape) {
    //unescape 是旧的方法，可能被遗弃，新的不支持
    const span = document.createElement("span");
    span.innerHTML = svgstr;
    const style = span.querySelector("svg").style.cssText || "";
    const base64str = window.btoa(unescape(encodeURI(svgstr)));
    svgstr = `<img style="display:inline-block;${style}" src="data:image/svg+xml;base64,${base64str}"/>`;
  }
  return svgstr;
}
// 初始化 marked option
marked.use({
  // use GitHub Flavored Markdown (GFM) specification
  gfm: true,
  //  add <br> on a single line break
  breaks: true
});

// code hightlight
marked.use(
  markedHighlight({
    langPrefix: "hljs language-",
    highlight(code, lang, info) {
      const language = hljs.getLanguage(lang) ? lang : "plaintext";
      return hljs.highlight(code, { language }).value;
    }
  })
);

// 渲染 katex 数学公式
marked.use(markedKatex({ throwOnError: false }));

// Flowchart.js 渲染流程图
const flowChartJS = {
  name: "flowChartJS",
  level: "block",
  start(src) {
    return src.match(/```flowchart/)?.index;
  },
  tokenizer(src, tokens) {
    const rule = /^```flowchart\n[^```]+```/g;
    const match = rule.exec(src);
    if (match) {
      return {
        type: "flowChartJS",
        raw: match[0],
        text: match[0].trim()
      };
    }
  },
  renderer(token) {
    const chart = FlowchartJS.parse(token.text.slice(12, -3));
    const htmlNode = document.querySelector("#hidden-rendering-container");
    htmlNode.innerHTML = "";
    chart.drawSVG("hidden-rendering-container", {});
    let svg = htmlNode.innerHTML;
    svg = svgToImg(svg);
    try {
      return `<p class="mermaid flow-chart">${svg}</p>`;
    } catch (error) {
      return `<p>${error}<p>`;
    }
  }
};

// mermaid 图
export const mermaidGraph = {
  name: "mermaid",
  level: "block",
  start(src) {
    return src.match(/```mermaid/)?.index;
  },
  tokenizer(src, tokens) {
    const rule = /^```mermaid(?=\s)\n(graph|sequenceDiagram|gantt|classDiagram|flowchart|stateDiagram|journey|pie title|requirementDiagram|gitGraph)\s[^```]+```/g;
    const match = rule.exec(src);
    const mermaidType = match && match[1]; // mermaid type
    if (match) {
      return {
        type: "mermaid",
        raw: match[0],
        text: match[0].trim(),
        mermaidType
      };
    }
  },
  renderer(token) {
    try {
      let svg = mermaid.render(
        "box-temp-render",
        token.text.slice(10, -3).trim()
      );
      svg = svgToImg(svg);
      return `<p class="mermaid ${token.mermaidType.replace(
        /[A-Z]+/g,
        str => "-" + str.toLowerCase()
      )}">${svg}<p>`;
    } catch (error) {
      return `<p>${error}<p>`;
    }
  }
};

marked.use({ extensions: [flowChartJS] });
export default marked;
